package com.rdc.example.dao.impl;

import com.rdc.example.entity.News;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import static com.rdc.example.util.DBUtil.closeResources;
import static com.rdc.example.util.DBUtil.getConnection;

public class NewsDaoImpl implements com.rdc.example.dao.NewsDao {

    @Override
    public boolean insert(News news) throws Exception {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            // 获取连接
            conn = getConnection();
            String sql = "insert into `news` (sender_id, receiver_id, content) values (?,?,?);";
            // 执行 sql 语句
            pstmt = conn.prepareStatement(sql);
            // 设值
            setNews(pstmt, news);
            // 以影响行数 row 判断并返回插入结果
            int row = pstmt.executeUpdate();
            return row > 0;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 释放资源
            closeResources(null, pstmt, conn);
        }
    }

    @Override
    public boolean batchInsertMessages(int senderId, String content, List<Integer> receiverIds) throws Exception {
        Connection conn =null;
        PreparedStatement pstmt = null;
        try {// 关闭自动提交
            conn = getConnection();
            conn.setAutoCommit(false);
            String sql = "insert into news (sender_id, receiver_id, content) values (?,?,?)";
            pstmt = conn.prepareStatement(sql);
            for (int receiverId : receiverIds) {
                pstmt.setInt(1, senderId);
                pstmt.setInt(2, receiverId);
                pstmt.setString(3, content);
                pstmt.addBatch();
            }
            int[] results = pstmt.executeBatch();
            conn.commit();
            // 全部成功返回true
            return true;
        } catch (SQLException e) {
            if (conn != null) {
                conn.rollback();
            }// 失败返回false
            return false;
        } finally {
            closeResources(null, pstmt, conn);
        }
    }

    @Override
    public boolean updateNews(Integer id) throws Exception {
         Connection conn = null;
         PreparedStatement pstmt = null;
         try {
             // 获取连接
             conn = getConnection();
             String sql = "update `news` set is_read = 1  where id=?";
             // 执行 sql 语句
             pstmt = conn.prepareStatement(sql);
             // 设值
             pstmt.setInt(1, id);
             // 以影响行数 row 判断并返回更新结果
             int row = pstmt.executeUpdate();
             return row > 0;
         } catch (Exception e) {
             throw new RuntimeException(e);
         } finally {
             // 释放资源
             closeResources(null, pstmt, conn);
         }
    }

    @Override
    public List<News> getNewsListByReceiverId(Integer receiverId, Integer pageBegin, Integer pageSize) throws Exception {
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<News> newsList = new ArrayList<>();
        try {
            String sql = "select * from `news` where receiver_id = ? limit ?,?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, receiverId);
            pstmt.setInt(2, pageBegin);
            pstmt.setInt(3, pageSize);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                // 循环获取结果
                News news = getNews(rs);
                newsList.add(news);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            // 释放资源
            closeResources(rs, pstmt, conn);
        }
        return newsList;
    }

    @Override
    public Integer countNewsByReceiverId(Integer receiverId) throws Exception {
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            String sql = "select count(*) from `news` where receiver_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, receiverId);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                return rs.getInt(1);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            // 释放资源
            closeResources(rs, pstmt, conn);
        }
        return 0;
    }




    // 从 ResultSet 中获取 News 对象的方法
    private News getNews(ResultSet rs) throws SQLException {
        News news = new News();
        news.setId(rs.getInt("id"));
        news.setSenderId(rs.getInt("sender_id"));
        news.setReceiverId(rs.getInt("receiver_id"));
        news.setContent(rs.getString("content"));
        news.setIsRead(rs.getInt("is_read"));
        news.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
        return news;
    }

    // 为 PreparedStatement 设置 News 对象参数的方法
    private void setNews(PreparedStatement pstmt, News news) throws SQLException {
        if (news.getSenderId() != null) {
            pstmt.setInt(1, news.getSenderId());
        } else {
            pstmt.setNull(1, java.sql.Types.INTEGER);
        }
        if (news.getReceiverId() != null) {
            pstmt.setInt(2, news.getReceiverId());
        } else {
            pstmt.setNull(2, java.sql.Types.INTEGER);
        }
        if (news.getContent() != null) {
            pstmt.setString(3, news.getContent());
        } else {
            pstmt.setNull(3, java.sql.Types.VARCHAR);
        }
    }
}
